#include "mem_chk_db.h"
#include <stdio.h>
#include "mem_leak_chk.h"
#include <string.h>

MemChkListNode gInfoHeader = {{0, 0, 0}, &gInfoHeader, &gInfoHeader};

void add_mem_chk_node(MemChkInfo* inf) {
	MemChkListNode* pnew = (MemChkListNode*)__real_malloc(sizeof(MemChkListNode));
	memset(pnew, 0, sizeof(MemChkListNode));
	pnew->info = *inf;
	
	MemChkListNode* ptail = gInfoHeader.pre;
	ptail->next = pnew;
	pnew->next = &gInfoHeader;
	gInfoHeader.pre = pnew;
	pnew->pre = ptail;
}

static void sub_rm_node(MemChkListNode* n) {
	if(NULL == n->info.ptr || &gInfoHeader == n) {
		return;
	}
	n->pre->next = n->next;
	n->next->pre = n->pre;
	__real_free(n->info.backtrace);
	__real_free(n);	
}

void rm_mem_chk_node(void* ptr) {
	MemChkListNode* i = gInfoHeader.next;
	while(&gInfoHeader != i) {
		if(i->info.ptr == ptr) {
			sub_rm_node(i);
			break;
		}	
		i = i->next;
	}
}

void print_mem_leak(bool is_clear_after_prit) {
	unsigned int idx = 0;
	MemChkListNode* i = gInfoHeader.next;
	printf("\n-----------------Mem Leak List:-----------------\n");
	while(&gInfoHeader != i) {
		printf("No.%u ptr=%p alloc_len=%u\n", idx++, i->info.ptr, i->info.alloc_len);
		printf("backtrace:\n");
		printf("%s", i->info.backtrace);
		printf("\n");
		
		if(is_clear_after_prit) {
			MemChkListNode* tmp = i;
			sub_rm_node(tmp);
			i = i->next;
		} else {
			i = i->next;
		}
	}
}